package com.lehecai.core.lottery.fetcher.lotterydraw.impl.worker;

import com.lehecai.core.lottery.LotteryType;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDraw;
import com.lehecai.core.lottery.fetcher.lotterydraw.LotteryDrawPrizeItem;
import com.lehecai.core.util.CoreDateUtils;
import com.lehecai.core.util.CoreFetcherUtils;
import org.apache.commons.lang.StringUtils;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.CssSelectorNodeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.Span;
import org.htmlparser.tags.TableColumn;
import org.htmlparser.tags.TableRow;
import org.htmlparser.tags.TableTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * 深圳彩票网 开奖结果抓取
 * 抓取深圳风采  <br/>
 * 历史地址:http://hbfc.cnhubei.com/22x5/index.shtml  <br/>
 * @author liurd
 *
 */
public class LotteryDrawFetch551WorkerOfficial extends AbstractLotteryDrawFetchWorker {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass().getName());
	//http://kaijiang.2caipiao.com/pages/allopenprized/detail_shenzhen.jsp?category=citylottery&lotteryType=szfc&issueNo=2011064&cityArea=shenzhen
	protected static final String RESULT_LOCALITY_URL = "http://www.szlottery.org/noticeview?type=_357";
	protected static final String RESULT_MORE_LOCALITY_URL = "http://www.szlottery.org/noticeview?type=_357&issue=";
	
	protected String siteName = "深圳彩票网";
	protected String lotteryScope = "深圳风采";
	
	public LotteryDrawFetch551WorkerOfficial() {
		super(LotteryType.A_SZFC);
	}
	
	@Override
	public LotteryDraw fetchResultDetail(String phase) {
		if (phase == null || "".equals(phase)) {
			phase = nowPhase();
		}
		if (phase == null || "".equals(phase)) {
			logger.error("==获取彩期错误==");
			return null;
		}
		//对方请求时加了个简单的处理
		String otherStr = "";
		try {
			otherStr = "'" + URLEncoder.encode(URLEncoder.encode("期", "UTF-8"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			logger.error(e.getMessage(), e);
		}

		String url = RESULT_MORE_LOCALITY_URL + phase + otherStr;
		
		String data = null;
		String pageInfo = "结果页面" + url;
		String encoding = "GBK";
		String logHeader = "==" + lotteryScope + "==" + siteName + "=="
				+ pageInfo + "==抓取==" + getLotteryType().getName() + "==";

		try {
			data = CoreFetcherUtils.URLGet(url, null, encoding);
		} catch (Exception e) {
			logger.error("获取html数据失败" + e.getMessage());
			return null;
		}
		
		if (data == null || data.indexOf("404 Not Found") > 0 || data.isEmpty()) {
			logger.error(logHeader + "data is null or 404 Not Found");
			return null;
		}
		Parser parser=null;
		NodeList nodeList = null;
		Parser timeDrawParser=null;
		NodeList timeDrawNodeList = null;
		parser = Parser.createParser(data,  encoding);
		timeDrawParser = Parser.createParser(data,  encoding);
		try {
			nodeList = parser.extractAllNodesThatMatch(new TagNameFilter("table"));
			timeDrawNodeList = timeDrawParser.extractAllNodesThatMatch(new CssSelectorNodeFilter("div[class=\"cpkj_nr01\"]"));
		} catch (ParserException e2) {
			logger.error(logHeader+ "连接错误==",e2);
			return null;
		}
		
		LotteryDraw tempLotteryDraw = new LotteryDraw();
		try {
			for (int i = 0; i < nodeList.size(); i++) {
				TableTag tableNode = (TableTag) nodeList.elementAt(i);
				String tableHtml = tableNode.toHtml();
				if (StringUtils.indexOf(tableHtml, "本期中奖号码") > 0) {
					tempLotteryDraw = this.getLotteryResult(tableNode, tempLotteryDraw);
				} else if (StringUtils.indexOf(tableHtml, "本期全国中奖情况") > 0) {
					tempLotteryDraw = this.getLotteryResultDetail(tableNode, tempLotteryDraw);
				}
			}
			
			Node timeDrawNode = (Node) timeDrawNodeList.elementAt(0);
			String tempHtml = timeDrawNode.toPlainTextString();
			String[] timeDrawArrayStart = tempHtml.split("开奖日期");
			if (timeDrawArrayStart.length == 2) {
				String[] timeDrawArrayEnd = timeDrawArrayStart[1].split("开奖时间");
				if (timeDrawArrayEnd.length == 2) {
					String timeDrawHtml = timeDrawArrayEnd[0].trim();
					timeDrawHtml = StringUtils.replace(timeDrawHtml, "：", "");
					timeDrawHtml = StringUtils.replace(timeDrawHtml, "&nbsp;", "");
					tempLotteryDraw.setTimeDraw(CoreDateUtils.formatDate(timeDrawHtml, "yyyy年MM月dd日", CoreDateUtils.DATETIME));
				}
			}
			tempLotteryDraw.setLotteryType(LotteryType.A_SZFC);
			//官网没有奖池信息
			tempLotteryDraw.setJackpot("0");
			//本期销量
			parser.setInputHTML(data);
			NodeList salesNodeList = null;
			try {
				salesNodeList = parser.extractAllNodesThatMatch(new CssSelectorNodeFilter("span[class=\"red02\"]"));
			} catch (ParserException e2) {
				logger.error(logHeader+ "连接错误==",e2);
				return null;
			}
			for (int i=0; i<salesNodeList.size(); i++) {
				Node spanNode = salesNodeList.elementAt(i);
				if (i == 1) {
					String volumeOfSales = spanNode.toPlainTextString().trim();
					volumeOfSales = StringUtils.replace(volumeOfSales, ",", "");
					tempLotteryDraw.setVolumeOfSales(volumeOfSales);
				} else if (i == 2) {
					String jackpot = spanNode.toPlainTextString().trim();
					jackpot = StringUtils.replace(jackpot, ",", "");
					tempLotteryDraw.setJackpot(jackpot);
				}
			}
		} catch (Exception e1) {
			logger.error(e1.getMessage(), e1);
			return null;
		}
		tempLotteryDraw.setPhase(phase);
		if (checkData(tempLotteryDraw)) {
			return tempLotteryDraw;
		}
		return null;
	}

	private String nowPhase() {
		String url = RESULT_LOCALITY_URL;
		
		String data = null;
		String pageInfo = "结果页面" + url;
		String encoding = "gbk";
		String logHeader = "==" + lotteryScope + "==" + siteName + "=="
				+ pageInfo + "==抓取==" + getLotteryType().getName() + "==";

		try {
			data = CoreFetcherUtils.URLGet(url, null, encoding);
		} catch (Exception e) {
			logger.error("获取html数据失败" + e.getMessage());
			return null;
		}
		
		if (data == null || data.indexOf("404 Not Found") > 0 || data.isEmpty()) {
			
			return null;
		}
		Parser parser=null;
		NodeList nodeList = null;
		parser= Parser.createParser(data,  encoding);
		try {
			nodeList = parser.extractAllNodesThatMatch(new CssSelectorNodeFilter("span[class=\"jc\"]"));
		} catch (ParserException e2) {
			logger.error(logHeader+ "连接错误==",e2);
			return null;
		}
		String tmpPhase = "";
		try {
			
			for (int i = 0; i < nodeList.size(); i++) {
				Span spanBlock = (Span) nodeList.elementAt(i);
				String divText = spanBlock.toPlainTextString();
				if (StringUtils.indexOf(divText, "201") > 0) {
					tmpPhase = divText;
				}
			}
			
		} catch (Exception e1) {
			logger.error("获取当前彩期错误", e1);
			return null;
		}
		
		if (StringUtils.isEmpty(tmpPhase)) {
			logger.error("获取当前彩期错误,彩期为空");
			return null;
		}
		
		tmpPhase = StringUtils.replace(tmpPhase, "第", "");
		tmpPhase = StringUtils.replace(tmpPhase, "期", "");
		if (tmpPhase.length() == 7) {
			return tmpPhase;
		} else {
			logger.error("获取当前彩期错误,彩期长度不等于7");
			return null;
		}
	}
	
	private LotteryDraw getLotteryResult(TableTag tableRow, LotteryDraw lotteryDraw) {
		TableRow[] tempList = tableRow.getRows();
		String result = "";
		for (int i=0;i<tempList.length;i++) {
			TableRow row = tempList[i];
			if (i == 2) {
				//开奖号
				NodeList resultNodeList = row.getColumns()[0].getChildren();
				for (int j=0; j<resultNodeList.size(); j++) {
					Node tempNode = resultNodeList.elementAt(j);
					String ulHtml = tempNode.toHtml();
					if (StringUtils.contains(ulHtml, "li")) {
						int num = 0;
						String liText = tempNode.toPlainTextString();
						if (StringUtils.isNotEmpty(liText)) {
							String[] liArray = StringUtils.split(liText, " ");
							for (String tempText : liArray) {
								if (StringUtils.isNotEmpty(tempText)) {
									if (num > 0) {
										result += ",";
									}
									result += tempText;
									num++;
								}
							}
						}
						break;
					}
				}
				String specialResult = row.getColumns()[1].toPlainTextString().trim();
				result += "," + specialResult;
				lotteryDraw.setResult(result);
			}
		}
		return lotteryDraw;
	}
	
	private LotteryDraw getLotteryResultDetail(TableTag tableRow, LotteryDraw lotteryDraw) {
		
		TableRow[] tempList = tableRow.getRows();
		//第三行开始取数
		List<LotteryDrawPrizeItem> lotteryDrawPrizeItemList = new ArrayList<LotteryDrawPrizeItem>();
		for (int i=2;i<tempList.length;i++) {
			TableRow row = tempList[i];
			TableColumn[] columns = row.getColumns();
			if (columns.length == 3) {
				LotteryDrawPrizeItem lotteryDrawPrizeItem = new LotteryDrawPrizeItem();
				lotteryDrawPrizeItem.setName(columns[0].toPlainTextString().trim());
				lotteryDrawPrizeItem.setWinningCount(columns[1].toPlainTextString().trim());
				lotteryDrawPrizeItem.setPrizeAmount(columns[2].toPlainTextString().trim());
				lotteryDrawPrizeItemList.add(lotteryDrawPrizeItem);
			}
		}
		lotteryDraw.setResultDetail(lotteryDrawPrizeItemList);
		return lotteryDraw;
	}
	
	private boolean checkData (LotteryDraw lotteryDraw) {
		
		//奖池
		if (StringUtils.isNotEmpty(lotteryDraw.getJackpot())) {
			try {
				lotteryDraw.setJackpot(Double.valueOf(lotteryDraw.getJackpot()).intValue() + "");
			} catch(Exception e) {
				logger.error(e.getMessage(), e);
				logger.error("获取本期奖池金额失败,奖池不是数字");
				return false;
			}
		}
		//销售额
		if (StringUtils.isNotEmpty(lotteryDraw.getVolumeOfSales())) {
			try {
				lotteryDraw.setVolumeOfSales(Double.valueOf(lotteryDraw.getVolumeOfSales()).intValue() + "");
			} catch(Exception e) {
				logger.error("获取本期奖池销售额失败,销售额不是数字");
				return false;
			}
		}
		
		//开奖结果
		if (StringUtils.isEmpty(lotteryDraw.getResult())) {
			logger.error("获取本期中奖号码失败,开奖结果为空");
			return false;
		} else if(StringUtils.split(lotteryDraw.getResult(), ",").length != 8) {
			logger.error("获取本期中奖号码失败，开奖结果不是8位");
			return false;
		} else if (StringUtils.isEmpty(lotteryDraw.getTimeDraw())) {
			logger.error("获取开奖结果错误");
			return false;
		}else {
			String[] resultArray = StringUtils.split(lotteryDraw.getResult(), ",");
			for (String result : resultArray) {
				if (StringUtils.isEmpty(result) || !StringUtils.isNumeric(result)) {
					logger.error("获取本期中奖号码失败，开奖结果为空或不是数字");
					return false;
				}
			}
		}
		return true;
	}

	@Override
	public LotteryDraw fetchResult(String phase) {
		return null;
	}

	@Override
	protected String getResultDetailUrl(String phase) {
		return null;
	}

	@Override
	protected String getResultUrl(String phase) {
		return null;
	}
}
